/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.thienloc.omap.util;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 *
 * @author Le Thanh Giang
 */
public class Styler {

    /**Chuỗi định dạng cho long date <br>
     * Eg: December 27, 1999
     */
    public static final String LONG_DATE = "%1$tB %1$td, %1$tY";//Eg: December 27, 1999
    /**Chuỗi định dạng cho full date <br>
     * Eg: Tuesday, December 27, 1999
     */
    public static final String FULL_DATE = "%1$tA, %1$tB %1$td, %1$tY";//Eg: Tuesday, December 27, 1999
    /**Chuỗi định dạng cho medium date <br>
     * Eg: Dec 27, 1999
     */
    public static final String MEDIUM_DATE = "%1$tb %1$td, %1$tY";//Eg: Dec 27, 1999
    /**Chuỗi định dạng cho short date, không phân tách <br>
     * Eg: 27121999
     */
    public static final String SHORT_DATE_NONE = "%1$td%1$tm%1$tY";//Eg: 27121999
    /**Chuỗi định dạng cho short date, phân tách bởi dấu chấm<br>
     * Eg: 27.12.1999
     */
    public static final String SHORT_DATE_DOT = "%1$td.%1$tm.%1$tY";//Eg: 27.12.1999
    /**Chuỗi định dạng cho short date, phân tách bởi dấu sổ chéo <br>
     * Eg: 27/12/1999
     */
    public static final String SHORT_DATE_SLASH = "%1$td/%1$tm/%1$tY";//Eg: 27/12/1999
    /**Chuỗi định dạng cho short date, phân tách bởi dấu gạch ngang <br>
     * Eg: 27-12-1999
     */
    public static final String SHORT_DATE_DASH = "%1$td-%1$tm-%1$tY";//Eg: 27-12-1999
    /**Chuỗi định dạng cho short date, phân tách bởi dấu cách<br>
     * Eg: 27 12 1999
     */
    public static final String SHORT_DATE_SPACE = "%1$td %1$tm %1$tY";//Eg: 27 12 1999
    /**Chuỗi định dạng cho short time, dạng 12h<br>
     * Eg: 01:11 PM
     */
    public static final String SHORT_TIME_12H = "%1$tI:%1$tM %1$Tp";//Eg: 01:11 PM
    /**Chuỗi định dạng cho long time, dạng 12h <br>
     * Eg: 01:11:33 PM
     */
    public static final String LONG_TIME_12H = "%1$Tr";//Eg: 01:11:33 PM
    /**Chuỗi định dạng cho short time, dạng 24h<br>
     * Eg: 13:11
     */
    public static final String SHORT_TIME_24H = "%1$tH:%1$tM";//Eg: 13:11
    /**Chuỗi định dạng cho long time, dạng 24h<br>
     * Eg: 13:11:33
     */
    public static final String LONG_TIME_24H = "%1$TT";//Eg: 13:11:33

    /**Định dạng cho cal bằng kiểu <code>style</code>
     *
     * @param cal Đối tượng calendar cần format
     * @param style Chuỗi định dạng. Nên dùng cách hằng chuỗi ở trên
     * @return Chuỗi ngày tháng đã được định dạng theo style
     */
    public static String format(Calendar cal, String style) {
        return String.format(style, cal);
    }

    /**Định dạng cho cal bằng kiểu <code>style</code>
     *
     * @param date Đối tượng date cần format
     * @param style Chuỗi định dạng. Nên dùng cách hằng chuỗi ở trên
     * @return Chuỗi ngày tháng đã được định dạng theo style
     */
    public static String format(Date date, String style) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return String.format(style, cal);
    }

    /**Định dạng <code>cal</code> theo chuỗi <code>format</code> tùy ý
     *    The following conversion characters are used for formatting times:
     *    'H' 	Hour of the day for the 24-hour clock, formatted as two digits with a leading zero as necessary i.e. 00 - 23.
     *    'I' 	Hour for the 12-hour clock, formatted as two digits with a leading zero as necessary, i.e. 01 - 12.
     *    'k' 	Hour of the day for the 24-hour clock, i.e. 0 - 23.
     *    'l' 	Hour for the 12-hour clock, i.e. 1 - 12.
     *    'M' 	Minute within the hour formatted as two digits with a leading zero as necessary, i.e. 00 - 59.
     *    'S' 	Seconds within the minute, formatted as two digits with a leading zero as necessary, i.e. 00 - 60 ("60" is a special value required to support leap seconds).
     *    'L' 	Millisecond within the second formatted as three digits with leading zeros as necessary, i.e. 000 - 999.
     *    'N' 	Nanosecond within the second, formatted as nine digits with leading zeros as necessary, i.e. 000000000 - 999999999.
     *    'p' 	Locale-specific morning or afternoon marker in lower case, e.g."am" or "pm". Use of the conversion prefix 'T' forces this output to upper case.
     *    'z' 	RFC 822 style numeric time zone offset from GMT, e.g. -0800.
     *    'Z' 	A string representing the abbreviation for the time zone. The Formatter's locale will supersede the locale of the argument (if any).
     *    's' 	Seconds since the beginning of the epoch starting at 1 January 1970 00:00:00 UTC, i.e. Long.MIN_VALUE/1000 to Long.MAX_VALUE/1000.
     *    'Q' 	Milliseconds since the beginning of the epoch starting at 1 January 1970 00:00:00 UTC, i.e. Long.MIN_VALUE to Long.MAX_VALUE.
     *
     *    The following conversion characters are used for formatting dates:
     *    'B' 	Locale-specific full month name, e.g. "January", "February".
     *    'b' 	Locale-specific abbreviated month name, e.g. "Jan", "Feb".
     *    'h' 	Same as 'b'.
     *    'A' 	Locale-specific full name of the day of the week, e.g. "Sunday", "Monday"
     *    'a' 	Locale-specific short name of the day of the week, e.g. "Sun", "Mon"
     *    'C' 	Four-digit year divided by 100, formatted as two digits with leading zero as necessary, i.e. 00 - 99
     *    'Y' 	Year, formatted as at least four digits with leading zeros as necessary, e.g. 0092 equals 92 CE for the Gregorian calendar.
     *    'y' 	Last two digits of the year, formatted with leading zeros as necessary, i.e. 00 - 99.
     *    'j' 	Day of year, formatted as three digits with leading zeros as necessary, e.g. 001 - 366 for the Gregorian calendar.
     *    'm' 	Month, formatted as two digits with leading zeros as necessary, i.e. 01 - 13.
     *    'd' 	Day of month, formatted as two digits with leading zeros as necessary, i.e. 01 - 31
     *    'e' 	Day of month, formatted as two digits, i.e. 1 - 31.
     *
     *
     * The following conversion characters are used for formatting common date/time compositions. 'R' 	Time formatted for the 24-hour clock as "%tH:%tM"
     *    'T' 	Time formatted for the 24-hour clock as "%tH:%tM:%tS".
     *    'r' 	Time formatted for the 12-hour clock as "%tI:%tM:%tS %Tp". The location of the morning or afternoon marker ('%Tp') may be locale-dependent.
     *    'D' 	Date formatted as "%tm/%td/%ty".
     *    'F' 	ISO 8601 complete date formatted as "%tY-%tm-%td".
     *    'c' 	Date and time formatted as "%ta %tb %td %tT %tZ %tY", e.g. "Sun Jul 20 16:17:00 EDT 1969".
     * @param cal Đối tượng <code>calendar</code> cần format
     * @param styleSequence Chuỗi ký tự định dạng (theo chuẩn conversion chars của StringFormatter class)
     * @return Chuỗi ngày tháng đã được định dạng theo <code>style</code>
     */
    public static String formatDateTime(Calendar cal, String styleSequence) {
        String strFommater = "";
        StringBuilder sb = new StringBuilder(styleSequence);
        String preserveStr = "";

        ArrayList<Character> inputStyles = new ArrayList<Character>();
        for (int i = 0; i < styleSequence.length(); i++) {
            inputStyles.add(styleSequence.charAt(i));
        }

        String strConversion = "HIklMSLNpzZsQBbhAaCYyjmdeTrDFc";

        int i = 0;
        do {
            if (strConversion.indexOf(inputStyles.get(i)) != -1) {
                strFommater += "%1$t" + inputStyles.get(i);
                i++;
            } else if (inputStyles.get(i) == '(') {
                preserveStr = sb.substring(i + 1, sb.indexOf(")", i));
                strFommater += preserveStr;
                i = sb.indexOf(")", i) + 1;
            } else {
                strFommater += inputStyles.get(i);
                i++;
            }
        } while (i < inputStyles.size());

        return String.format(strFommater, cal);
    }

    public static String formatDateTime(Date date, String styleSequence) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return Styler.formatDateTime(cal, styleSequence);
    }

    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        System.out.println(Styler.format(cal, Styler.MEDIUM_DATE));
        System.out.println(Styler.format(new Date(), Styler.MEDIUM_DATE));
        System.out.println(Styler.formatDateTime(cal, "d/m/Y r"));
        System.out.println(Styler.formatDateTime(new Date(), "d/m/Y r"));

    }
}
